/**
 * 
 */
package com.yuyi.tools;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 *
 * @author 李文庆
 * 2018年7月20日 下午3:43:51
 */
public class ZxingCode {
	
	private Logger logger = LoggerFactory.getLogger(ZxingCode.class);
	
	private static final int BLACK = 0xff000000;
	private static final int WHITE = 0xFFFFFFFF;
	
	private static final int width = 300;
	private static final int height = 300;
	private static final String format = "png";
	
	private String content;
	private String picName;
	private String storePath;
	private boolean logo;
	private String logoPath;
	
	public ZxingCode(){
		
	}
	/**
	 * @param content 二维码文本信息
	 * @param picName 生成的二维码图片文件名
	 * @param storePath 二维码存储路径
	 */
	public ZxingCode(String content,String picName,String storePath){
		this(content,picName,storePath,false,null);
	}
	
	/**
	 * @param content 二维码文本信息
	 * @param picName 生成的二维码图片文件名
	 * @param storePath 二维码存储路径
	 * @param logo 是否添加logo
	 * @param logoPath logo图片的路径
	 */
	public ZxingCode(String content,String picName,String storePath,boolean logo,String logoPath) {
		
		this.content = content;
		this.picName = picName;
		this.storePath = storePath;
		this.logo = logo;
		this.logoPath = logoPath;
	}
	
	/**生成二维码
	 * @return
	 * @throws IOException
	 * @throws WriterException
	 */
	public String encode() throws IOException, WriterException{
		   
		String payCodeName = picName+LocalDateTimeTools.formatNow("yyyyMMddHHmmss");
		   
		/**设置二维码参数*/
		Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType, Object>();
		hints.put(EncodeHintType.CHARACTER_SET,"utf-8");    //指定字符编码为“utf-8”
	    hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
	    hints.put(EncodeHintType.MARGIN,1);    //设置图片的边距
	      
	    BitMatrix bitMatrix=new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height,hints);
	    Path file=new File(storePath+payCodeName+".png").toPath();
	    
	    /**不带logo的二维码*/
	    if (Objects.equals(logo,false)) {
	    	MatrixToImageWriter.writeToPath(bitMatrix, format, file);
		}
	    /**带logo的二维码*/
	    if (Objects.equals(logo,true)) {
	    	logger.info("带logo");
	    	this.writeToFile(bitMatrix,new File(storePath+payCodeName+".png"));
		}
	    
	    String picPath = storePath+payCodeName+".png";
	      
		return picPath;
	}
	
	/**解析二维码
	 * @param file1
	 * @throws Exception 
	 */
	public Result decode(String filePath) throws Exception{
		
        MultiFormatReader formatReader=new MultiFormatReader();
        File file=new File(filePath);
        BufferedImage image;
   
        image = ImageIO.read(file);
        BinaryBitmap binaryBitmap=new BinaryBitmap(new HybridBinarizer
                                    (new BufferedImageLuminanceSource(image)));

        Map<DecodeHintType,String> hints=new HashMap<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET,"utf-8");    //指定字符编码为“utf-8”

        Result result=formatReader.decode(binaryBitmap,hints);
        
        return result;
    }
	
	public void writeToFile(BitMatrix bitMatrix,File file) throws IOException{
		
		BufferedImage bi = toBufferedImageContents(bitMatrix);
		
		int width_4 = bitMatrix.getWidth() / 4;
		int width_8 = width_4 / 2;
		int height_4 = bitMatrix.getHeight() / 4;
		int height_8 = height_4 / 2;
		/*返回由指定矩形区域定义的子图像*/
		BufferedImage bi2 = bi.getSubimage(width_4 + width_8, height_4 + height_8, width_4, height_4);
		/*获取一个绘图工具笔*/
		Graphics2D g2 = bi2.createGraphics();
		/*读取logo图片信息*/
		Image img = ImageIO.read(new File(logoPath));//实例化一个Image对象。
		/*当前图片的宽与高*/
		int currentImgWidth = img.getWidth(null);
		int currentImgHeight = img.getHeight(null);
		/*处理图片的宽与高*/
		int resultImgWidth = 0;
		int resultImgHeight = 0;
		if(currentImgWidth != width_4){
			resultImgWidth = width_4;
		}
		if(currentImgHeight != width_4){
			resultImgHeight = width_4;
		}
	    /*绘制图片*/
		g2.drawImage(img,0,0, resultImgWidth,resultImgHeight,null);
	    g2.dispose();  
	    bi.flush();

		ImageIO.write(bi, format, file);
	}

	
	/**BitMatrix转为img，即对生成的二维码图片进行二次加工。
	 * @param bitMatrix
	 * @return
	 */
	public BufferedImage toBufferedImageContents(BitMatrix bitMatrix){
		int width = bitMatrix.getWidth();
		int height = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		for(int x=0;x<width;x++){
			for(int y=0;y<height;y++){
				image.setRGB(x, y, bitMatrix.get(x, y) == true ? BLACK : WHITE);
			}
		}
		return image;
	}

	
}
